# -*- coding:utf-8 -*-
import os,sys
import re
import traceback
import time
import urllib
import urllib2
import cookielib
import random
from PIL import Image
from prettytable import PrettyTable
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.alert import Alert
from selenium.webdriver import firefox
from selenium.common.exceptions import NoAlertPresentException
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), os.pardir, os.pardir))
import supeanut_config
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), os.pardir))
from CommonLib.mylog import *


'''
作者：supeanut
创建时间：2016-12-11 16:06
功能描述：
	提供方正证券等web交易的python接口
历史改动：
	2016-xx-xx: xxxxxx
'''
class WebTradeClient:
	def __init__(self, ):
		self.browser = None
		self.zhengQuan = None
		self.account = None
		self.passWord = None

	# close all browser driver related processes
	def closeAllPros(self):
		os.system('ps xf|grep firefox|grep -v grep|awk \'{print $1}\'|xargs kill -9')
		os.system('ps xf|grep geckodriver|grep -v grep|awk \'{print $1}\'|xargs kill -9')
		os.system('ps xf|grep dbus-launch|grep -v grep|awk \'{print $1}\'|xargs kill -9')
		os.system('ps xf|grep dbus-daemon|grep -v grep|awk \'{print $1}\'|xargs kill -9')
		
	def initClient(self, zhengQuan, account, passWord):
		try:
			self.browser.quit()
		except:
			pass
		self.closeAllPros()
		self.zhengQuan = zhengQuan
		self.account = account
		self.passWord = passWord
		flag = False
		while not flag:
			if zhengQuan == 'FangZheng':
				flag, msg = self.fangZhengLogin(account, passWord)
		
	
	def acceptAllAlert(self, ):
		str_list = []
		log = mylog('WebTradeClient', None)
		browser = self.browser
		while True:
			try:
				alt = browser.switch_to_alert()
				alt_text = alt.text.encode('utf-8')
				log.info('Alert Dialog:' + alt_text)
				str_list.append(alt_text)
				alt.accept()
				time.sleep(2)
			except NoAlertPresentException:
				return True, str_list
			except:
				log.info(traceback.format_exc())
				return True, str_list

			
		
	def sell(self, code, price, vol_stock, trade_mod):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengSell(code, price, vol_stock, trade_mod)

	def buy(self, code, price, vol_stock, trade_mod):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengBuy(code, price, vol_stock, trade_mod)

	def hold(self, ):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengHold()

	def cancel(self, weiTuoBiaoHao, mod):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengCancel(weiTuoBiaoHao, mod)

	def record(self, ):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengRecord()

	def logout(self, ):
		if self.zhengQuan == 'FangZheng':
			return self.fangZhengLogout()

	def img2str(self, img_path):
		os.system('tesseract %s validstr -l eng'%img_path)
		time.sleep(2)
		f = open('validstr.txt', 'rb')
		f_str = f.read()
		f_str = f_str.replace('\n','')
		f_str = f_str.replace(' ','')
		return f_str


	def fangZhengLogin(self, account, passWord):
		log = mylog('WebTradeClient', None)
		log.info('start login fangZheng')
		try:
			browser = webdriver.Firefox()
			self.browser = browser
			browser.get("https://trade.foundersc.com/")
			try:
				alt = Alert(browser)
				#log.info('WebAlert: %s'%alt.text)
				#alt.dismiss()
			except:
				pass
			e1 = browser.find_element_by_id("Text1")
			e1.send_keys(account)
			img1 = browser.find_element_by_id("img1")
			img1.click()
			img3 = browser.find_element_by_id("img3")
			try:
				img3.click()
			except:
				pass
			e2 = browser.find_element_by_id("Text2")
			e2.send_keys(passWord)
			e3 = browser.find_element_by_id("Text3")
			try_count = 0
			while True:
				try_count += 1
				log.info('trying %d time'%try_count)
				if try_count >= 20:
					return False, 'valid img try max'
				#valid_img_url = img1.get_attribute("src")
				#print valid_img_url
				browser.save_screenshot("validimg.jpg")
				x1 = img1.location['x']
				y1 = img1.location['y']
				x2 = x1 + img1.size['width']
				y2 = y1 + img1.size['height']
				bbox = (x1,y1,x2,y2)
				validimg = Image.open("validimg.jpg")
				validimg = validimg.crop(bbox)
				validimg.save("validimg.jpg")
				num_str = self.img2str("validimg.jpg")
				log.info('valid img: %s'%num_str)
				#print num_str
				if len(num_str) <> 5 or not num_str.isdigit():
					img1.click()
					time.sleep(2)
					log.warning('recog failed %s, retry...'%num_str)
					continue
				log.info('submit login')
				e3.clear()
				e3.send_keys(num_str)
				btn = browser.find_element_by_id("dljybtn")
				btn.click()
				time.sleep(3)
				alt_text = ""
				try:
					alt = Alert(browser)
					alt_text = alt.text
					log.info('Alert Dialog: %s'%alt_text)
					alt.dismiss()
				except:
					pass
				if alt_text.find(u'验证码错误') >= 0:
					img1.click()
					time.sleep(5)
					log.warning('submit valid img %s failed, retry...'%num_str)
					continue
				if alt_text.find(u'转发错误') >= 0:
					log.warning('服务器转发错误, retry...')
					return False, '服务器转发错误'
				if alt_text.find(u'requesting your username and password') >= 0:
					log.info('login suc')
					break
				log.info('some error in login')
				return False, 'some error in login'
			#browser.get("https://trade.foundersc.com/content/Sale.aspx?type=1&gpdm=1")
			#print browser.page_source.encode('utf-8')
		except:
			log.error(traceback.format_exc())
			return False, traceback.format_exc()
		return True, 'suc'
		

	def fangZhengCheckAliveAndGet(self, url):
		log = mylog('WebTradeClient', None)
		log.info('access %s'%url)
		browser = self.browser
		browser.get(url)
		page_str = browser.page_source.encode('utf-8')
		# 服务器状态检查
		if page_str.find("系统出现了异常") >= 0:
			return False, "系统出现了异常,通常为服务器标记错误"
		if page_str.find("aspNetHidden") >= 0:
			return False, "连接问题：aspNetHidden"
		if page_str.find("HTTP Error 503") >= 0 and page_str.find("The service is unavailable") >= 0:
			return False, "HTTP 503"
		#log.info(page_str)
		# 设置等待某个元素
		return True, 'suc'

	def fangZhengForceAccess(self, url):
		log = mylog('WebTradeClient', None)
		flag = False
		while not flag:
			flag, msg = self.fangZhengCheckAliveAndGet(url)
			if flag is False:
				log.info('access disconnected, reLogin fangZheng')
				self.initClient(self.zhengQuan, self.account, self.passWord)
	

	def fangZhengSell(self, code, price, vol_stock, trade_mod):
		log = mylog('WebTradeClient', None)
		if trade_mod == 'shijia':
			#return False, 'not support %s now'%trade_mod
			log.warning('shijia mode: just xianjia mod by cur price')
		self.fangZhengForceAccess("https://trade.foundersc.com/content/Sale.aspx")
		self.acceptAllAlert()
		browser = self.browser
		# https://trade.foundersc.com/WTCX/Drcjcx.aspx 成交
		# https://trade.foundersc.com/content/Wtcd.aspx 撤单
		try:
			zqdm = browser.find_element_by_id('zqdm')
			zqdm.send_keys(code)
			mrjg = browser.find_element_by_id('mrjg')
			mrjg.click()
			if trade_mod == 'xianjia':
				mrjg.clear()
				mrjg.send_keys(price)
			mrsl = browser.find_element_by_id('mrsl')
			mrsl.send_keys(vol_stock)
			btn = browser.find_element_by_id('Button2')
			#browser.save_screenshot("sell.jpg")
			btn.click()
		except:
			return False, traceback.format_exc()
		flag, str_list = self.acceptAllAlert()
		return True, str_list

	def fangZhengHold(self, ):
		log = mylog('WebTradeClient', None)
		self.fangZhengForceAccess("https://trade.foundersc.com/content/Zjgf.aspx")
		self.acceptAllAlert()
		browser = self.browser
		try:
			captical_infos = browser.find_elements_by_xpath(r"//*[@id='form1']/div[2]/table/tbody/tr[1]/td/table/tbody/tr/td")
			shengyu = captical_infos[1].text.encode('utf-8').split(' ')[1]
			keyong = captical_infos[3].text.encode('utf-8')
			shizhi = captical_infos[5].text.encode('utf-8')
			zichan = captical_infos[7].text.encode('utf-8')
			fudongYingkui = captical_infos[9].text.encode('utf-8')
			table = PrettyTable(["余额","可用资金","当前市值","资产","浮动盈亏"])
			table.add_row([shengyu,keyong,shizhi,zichan,fudongYingkui])
			print table
			stock_infos = browser.find_elements_by_xpath(r"//*[@id='pl']/table/tbody/tr")
			table = PrettyTable(["证券名称","证券数量","可卖数量","成本价","浮动盈亏","最新市值","当前价","证券代码","股东代码"])
			for stock_info in stock_infos:
				stock_detail = stock_info.find_elements_by_tag_name("td")
				table.add_row([stock_detail[1].text.encode('utf-8'),\
							   stock_detail[2].text.encode('utf-8'),\
							   stock_detail[3].text.encode('utf-8'),\
							   stock_detail[4].find_element_by_tag_name("input").get_attribute("value").encode('utf-8'),\
							   stock_detail[5].text.encode('utf-8'),\
							   stock_detail[6].text.encode('utf-8'),\
							   stock_detail[7].text.encode('utf-8'),\
							   stock_detail[9].text.encode('utf-8'),\
							   stock_detail[10].text.encode('utf-8')])
			print table
			return True, 'suc'
		except:
			log.error(traceback.format_exc())
			return False, traceback.format_exc()

	def fangZhengBuy(self, code, price, vol_stock, trade_mod):
		log = mylog('WebTradeClient', None)
		if trade_mod == 'shijia':
			#return False, 'not support %s now'%trade_mod
			log.warning('shijia mode: just xianjia mod by cur price')
		self.fangZhengForceAccess("https://trade.foundersc.com/content/Buy.aspx")
		self.acceptAllAlert()
		browser = self.browser
		try:
			zqdm = browser.find_element_by_id('zqdm')
			zqdm.send_keys(code)
			mrjg = browser.find_element_by_id('mrjg')
			mrjg.click()
			if trade_mod == 'xianjia':
				mrjg.clear()
				mrjg.send_keys(price)
			mrsl = browser.find_element_by_id('mrsl')
			mrsl.send_keys(vol_stock)
			btn = browser.find_element_by_id('Button2')
			#browser.save_screenshot("buy.jpg")
			btn.click()
		except:
			return False, traceback.format_exc()
		flag, str_list = self.acceptAllAlert()
		return True, str_list

	def fangZhengCancel(self, weiTuoBiaoHao, mod):
		log = mylog('WebTradeClient', None)
		self.fangZhengForceAccess("https://trade.foundersc.com/content/Wtcd.aspx")
		self.acceptAllAlert()
		browser = self.browser
		#print browser.page_source.encode('utf-8')
		if mod == 'look':
			try:
				table = PrettyTable(["证券名称","买卖标志","委托价格","委托数量","成交价格","成交数量","状态说明",\
									 "委托时间","委托编号","证券代码","股东代码","报价方式"])
				weiTuo_infos = browser.find_elements_by_xpath(r"//*[@id='pl']/div/table/tbody/tr")
				for weiTuo in weiTuo_infos:
					weiTuo_items = weiTuo.find_elements_by_tag_name("td")
					table.add_row([
						weiTuo_items[1].text.encode('utf-8'),
						weiTuo_items[2].text.encode('utf-8'),
						weiTuo_items[3].text.encode('utf-8'),
						weiTuo_items[4].text.encode('utf-8'),
						weiTuo_items[5].text.encode('utf-8'),
						weiTuo_items[6].text.encode('utf-8'),
						weiTuo_items[7].text.encode('utf-8'),
						weiTuo_items[8].text.encode('utf-8'),
						weiTuo_items[9].text.encode('utf-8'),
						weiTuo_items[10].text.encode('utf-8'),
						weiTuo_items[11].text.encode('utf-8'),
						weiTuo_items[12].text.encode('utf-8')])
				return True, 'suc'
				print table
			except:
				return False, traceback.format_exc()
			return
		elif mod == 'submit':
			try:
				weiTuo_infos = browser.find_elements_by_xpath(r"//*[@id='pl']/div/table/tbody/tr")
				for weiTuo in weiTuo_infos:
					weiTuo_items = weiTuo.find_elements_by_tag_name("td")
					weiTuoNo = weiTuo_items[9].text.encode('utf-8')
					if weiTuoNo <> weiTuoBiaoHao:
						continue
					checkbox = weiTuo_items[0]
					checkbox.click()
					submit_btn = browser.find_element_by_xpath(r"//*[@id='Button1']")
					submit_btn.click()
					flag, str_list = self.acceptAllAlert()
					break
				return True, str_list
			except:
				return False, traceback.format_exc()
		elif mod == 'submitAll':
			try:
				AllSelected_box = browser.find_element_by_xpath(r"//*[@id='Checkbox2']")
				AllSelected_box.click()
				submit_btn = browser.find_element_by_xpath(r"//*[@id='Button1']")
				submit_btn.click()
				flag, str_list = self.acceptAllAlert()
				return True, str_list
			except:
				return False, traceback.format_exc()
		else:
			return False, 'mod error: must in look or submit or submitAll'

	def fangZhengRecord(self, ):
		log = mylog('WebTradeClient', None)
		self.fangZhengForceAccess("https://trade.foundersc.com/WTCX/Drcjcx.aspx")
		self.acceptAllAlert()
		browser = self.browser
		try:
			table = PrettyTable(["证券名称","成交时间","买卖标志","成交价格","成交数量",\
								 "成交金额","成交编号","委托编号","证券代码","股东代码"])
			trade_infos = browser.find_elements_by_xpath(r"//*[@id='pl']/table/tbody/tr")
			for trade in trade_infos:
				trade_items = trade.find_elements_by_tag_name("td")
				table.add_row([
					trade_items[0].text.encode('utf-8'),
					trade_items[1].text.encode('utf-8'),
					trade_items[2].text.encode('utf-8'),
					trade_items[3].text.encode('utf-8'),
					trade_items[4].text.encode('utf-8'),
					trade_items[5].text.encode('utf-8'),
					trade_items[6].text.encode('utf-8'),
					trade_items[7].text.encode('utf-8'),
					trade_items[8].text.encode('utf-8'),
					trade_items[9].text.encode('utf-8')])
			print table
			return True, 'suc'
		except:
			log.error(traceback.format_exc())
			return False, traceback.format_exc()
		

	def fangZhengLogout(self, ):
		#self.fangZhengForceAccess("https://trade.foundersc.com/FzIndex/Top.aspx")
		flag, msg = self.fangZhengCheckAliveAndGet("https://trade.foundersc.com/FzIndex/Top.aspx")
		if flag is False:
			return True, 'not alived'
		self.acceptAllAlert()
		browser = self.browser
		try:
			quit_link = browser.find_element_by_xpath(r"//*[@id='form1']/div[2]/table[1]/tbody/tr/td/table/tbody/tr/td/table[2]/tbody/tr[1]/td[5]/a")
			quit_link.click()
			self.acceptAllAlert()
		except:
			pass



if __name__ == '__main__':
	obj = WebTradeClient()
	obj.initClient('FangZheng','zhanghao','mima')
	#obj.sell('601179', '6.10', '200', 'xianjia')
	#obj.sell('601177', '', '100', 'shijia')
	#print obj.buy('601177', '11.5', '100', 'xianjia')
	#obj.hold()
	#print obj.cancel('', 'look')
	#print obj.cancel('', 'submitAll')
	#print obj.cancel('6301', 'submit')
	#obj.record()
	#obj.logout()
	while True:
		obj.record()
		obj.hold()
		#obj.buy('601177', '11.5', '100', 'xianjia')
		#obj.sell('601177', '', '100', 'shijia')
		#obj.cancel('', 'look')
		time.sleep(random.randint(1, 20))
